/*
 * Copyright 2007-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.paoding.rose.web.impl.thread;

/**
 * {@link Path}用于解析一次请求的URI，形成module,controller以及actionPath等项目
 * 
 * @author qieqie.wang@paoding.net
 * 
 */
public class Path {

	private String uri;
	private String ctx; // = request.getContextPath

	// = 去掉ctxpath的URI剩下部分，以'/'开头?;
	// =modulePath+controllerPath+actionPath
	private String info;
	private String module;
	//
	private String firstSenceController;
	private String firstSenceAction;
	private String controllerInfo; // = controller + action
	private String controller;
	private String action;

	public Path(String uri, String ctxpath, String info, String modulePath) {
		this.uri = uri;
		this.ctx = ctxpath;
		this.info = info;
		this.module = modulePath;
		parse(info);
		this.firstSenceController = controller;
		this.firstSenceAction = action;
		this.controllerInfo = controller + action;
	}
	
	public void injectDefaultControllerPath(String defaultControllerPath) {
		this.controller = defaultControllerPath;
		this.action = firstSenceController + firstSenceAction;
		this.controllerInfo = controller + action;
	}
	
	public void setControllerPath(String newValue) {
		if (!info.startsWith(module + newValue)){
			throw new IllegalArgumentException("the new controllerPath '"+ newValue + "' should be the prefix of uri " + info.substring(module.length()));
		}
		if (newValue.endsWith("/")) {
			throw new IllegalArgumentException("the new controllerPath '"+ newValue + "' should not end of '/'");
		}
		this.controller = newValue;
		this.action = info.substring(module.length() + controller.length());
		if ("/".equals(this.action)) {
			this.action = "";
		}
	}

	protected void parse(String info) {
		controller = null;
		int last = module.length() + 1;
		for (int i = last; i < info.length(); i++) {
			char ch = info.charAt(i);
			if (ch == '/') {
				if (info.charAt(i - 1) != '/') {
					String elem = info.substring(last, i);
					controller = elem.length() == 0 ? "" : "/" + elem;
					if (i + 1 == info.length()) {
						action = "";
					} else {
						action = info.substring(i);
					}
					break;
				}
				last = i + 1;
			}
		}
		if (controller == null) {
			if (info.length() > last) {
				String elem = info.substring(last);
				controller = elem.length() == 0 ? "" : "/" + elem;
				action = "";
			} else {
				controller = "";
				action = "";
			}
		}
	}

	public String getCtx() {
		return ctx;
	}

	public String getUri() {
		return uri;
	}

	public String getInfo() {
		return info;
	}

	public String getModule() {
		return module;
	}

	public String getController() {
		return controller;
	}

	public String getAction() {
		return action;
	}
	
	public String getControllerInfo() {
		return controllerInfo;
	}

	@Override
	public String toString() {
		return "ctxpath=" + ctx + "; pathInfo=" + info + "; modulePath=" + module
				+ "; controllerPath=" + controller + "; actionPath=" + action;
	}

}
